package workgroup.osaka.DirectLink;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

import android.app.IntentService;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;

/*
 * このクラスを使用する時はマニフェストに以下の記述が必要
 * 
 *・サービスを使うために必要
 *  <service android:enabled="true" android:name=".FileTransService" />
 *  
 * ・インターネットへのアクセスを許可するために必要
 * <uses-permission android:name="android.permission.INTERNET" />
 */

//ファイル送信
public  class FileTransferService extends IntentService {

	private static final int SOCKET_TIMEOUT = 5000;
	public static final String ACTION_SEND_FILE = "workgroup.osaka.DirectLink.SEND_FILE";
	public static final String EXTRAS_FILE_PATH = "file_url";
	public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host";
	public static final String EXTRAS_GROUP_OWNER_PORT = "go_port";
	
	public static final String ACTION_SEND_CLIENTIP = "clientIP";
	public static final String CLIENT_IP = "clientIP";
	String ClientIP = null;
	
	public FileTransferService(String name) {
		super(name);
		Log.d("送信１", "コンストラクタ");
	}

	public FileTransferService() {
		super("FileTransferService");
		Log.d("送信２", "コンストラクタ");
	}
	
	@Override
	protected void onHandleIntent(Intent intent) {
		
		
		Context context = getApplicationContext();
		Log.d("送信３", "getApplicationContext()");

		
		if (intent.getAction().equals(ACTION_SEND_FILE)) {
			
			//送信ファイルの位置を取得
			Log.d("送信４", "送信ファイルの位置取得");
			String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);

			//相手のアドレス取得
			String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);

			//相手との通信に利用するソケットを用意③
			Socket socket = new Socket();
			

			//相手との通信に利用するportを取得
			int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
			Log.d("アクションセンドファイル", ACTION_SEND_FILE);
			Log.d("ファイルパス", fileUri);
			Log.d("オーナーアドレス", host);
			Log.d("オーナーポート", "" + port);

			try {
				Log.d("送信５", "Opening client socket - ");
				//バインド④
				socket.bind(null);
				//相手との接続開始⑤
				socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
				Log.d("送信６", "Client socket - " + socket.isConnected());

				//相手との通信路の設定
				OutputStream stream = socket.getOutputStream();

				//
				ContentResolver cr = context.getContentResolver();

				//初期化？
				InputStream is = null;
				try {
					//読み込みファイルの準備 ⑦
					is = cr.openInputStream(Uri.parse(fileUri));
				} catch (FileNotFoundException e) {
					Log.d("送信７", e.toString());
				}

				//ファイルから読み込み、通信路にデータを流す⑧
				copyFile(is, stream);
				Log.d("送信８", "Client: Data written");
			} catch (IOException e) {
				Log.e("送信９", e.getMessage());
			} finally {
				if (socket != null) {
					if (socket.isConnected()) {
						try {
							//ソケットが接続されていたらclose処理⑪
							socket.close();
						} catch (IOException e) {
							// Give up
							//エラー処理？
							e.printStackTrace();
						}
					}
				}
			}
		}else if(intent.getAction().equals(ACTION_SEND_CLIENTIP)){
			//相手のアドレス取得
			String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);

			//相手との通信に利用するソケットを用意③
			Socket socket = new Socket();

			//相手との通信に利用するportを取得
			int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
			
			ClientIP = intent.getExtras().getString(CLIENT_IP);
			
			try {
				
				Log.d("送信A", "Opening client socket - ");
				//バインド④
				socket.bind(null);
				
				//相手との接続開始⑤
				socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
				Log.d("送信B", "Client socket - " + socket.isConnected());

				//相手との通信路の設定
				OutputStream stream = socket.getOutputStream();

				//クライアントのＩＰの文字列を、通信路にデータを流す⑧
				SendClientIP(stream);
				Log.d("送信C", "Client: Data written");
			} catch (IOException e) {
				Log.e("送信D", e.getMessage());
			} finally {
				if (socket != null) {
					if (socket.isConnected()) {
						try {
							//ソケットが接続されていたらclose処理⑪
							socket.close();
						} catch (IOException e) {
							// Give up
							//エラー処理？
							e.printStackTrace();
						}
					}
				}
			}
		}
	}

	//ファイル書き込みの際に使用
	private boolean copyFile(InputStream inputStream, OutputStream out) {
		byte buf[] = new byte[1024];
		int len;
		try {
			while ((len = inputStream.read(buf)) != -1) {
				out.write(buf, 0, len);
			}
			Log.d("copyFile", "アウトプットストリームに画像ファイル書き込み");
			out.close();
			inputStream.close();
		} catch (IOException e) {
			Log.d("アウトプットストリームに画像ファイル書き込みエラー", e.toString());
			return false;
		}
		return true;
	}
	
	//自端末のＩＰを送信する際に使用
	private boolean SendClientIP(OutputStream out) {
		byte buf[] = new byte[1024];
		try {
			String str = ClientIP;
			Log.d("アウトプットストリームにＩＰ書き込み", str);
			buf = str.getBytes("UTF-8");
			WiFiDirect.ClientIP = str;
			out.write(buf);
			out.close();
		} catch (IOException e) {
			Log.d("アウトプットストリームにＩＰ書き込みエラー", e.toString());
			return false;
		}
		return true;
	}
}
